package com.zengqingfa.examples.mybatisplus.aspect;

import com.zengqingfa.examples.mybatisplus.annotation.LogHistory;
import com.zengqingfa.examples.mybatisplus.common.OperateType;
import com.zengqingfa.examples.mybatisplus.entity.BaseLog;
import com.zengqingfa.examples.mybatisplus.entity.User;
import com.zengqingfa.examples.mybatisplus.entity.UserHistory;
import com.zengqingfa.examples.mybatisplus.service.UserHistoryService;
import com.zengqingfa.examples.mybatisplus.service.UserService;
import com.zengqingfa.examples.mybatisplus.util.CompareUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 *
 * @fileName: LogHistoryAspect
 * @author: zengqf3
 * @date: 2021-4-6 15:20
 * @description:
 */
@Component
@Aspect
@Slf4j
public class LogHistoryAspect {

    @Autowired
    private UserService userService;
    @Autowired
    private UserHistoryService userHistoryService;

    //拦截 LogHistory注解
    @Pointcut("@annotation(com.zengqingfa.examples.mybatisplus.annotation.LogHistory)")
    private void logHistoryPointCut() {
        //logHistoryPointCut 日志注解切点
    }

    @Around("logHistoryPointCut()")
    public Object historyAround(ProceedingJoinPoint pjp) {
        //获取参数
        Object[] args = pjp.getArgs();
        log.info("参数args:{}", args);
        User user = (User) args[0];
        //获取方法
        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
        // 获取LogHistory注解
        LogHistory logHistory = method.getAnnotation(LogHistory.class);
        OperateType operateType = logHistory.operateType();
        Object returnVal = null;
        try {
            //执行方法前
            User oldUser = userService.selectById(user.getId());
            try {
                //执行方法
                returnVal = pjp.proceed();
            } catch (Throwable e) {
                log.error("e:{}", e.getMessage());
            }
            //执行方法后
            User newUser = userService.selectById(user.getId());
            //查询上一条记录
            UserHistory userHistory = new UserHistory();
            //记录历史记录
            BeanUtils.copyProperties(newUser, userHistory);
            userHistory.setUserId(user.getId());
            switch (operateType) {
                case ADD:
                    userHistory.setOperateType(OperateType.ADD.getKey());
                    break;
                case UPDATE:
                    setVal(oldUser, newUser, userHistory, OperateType.UPDATE);
                    break;
                case DELETE:
                    setVal(oldUser, newUser, userHistory, OperateType.DELETE);
                    break;
                default:
            }
            userHistoryService.save(userHistory);
        } catch (Exception e) {
            log.error("e:{}", e);
        }
        return returnVal;
    }

    private void setVal(User oldUser, User newUser, UserHistory userHistory, OperateType operateType)
            throws IllegalAccessException {
        userHistory.setOperateType(operateType.getKey());
        //对比记录
        BaseLog baseLog1 = CompareUtil.comparatorObject(oldUser, newUser);
        userHistory.setId(null);
        userHistory.setUpdateField(baseLog1.getUpdateField());
        userHistory.setUpdateFieldValue(baseLog1.getUpdateFieldValue());
    }
}
